﻿using System;
using System.Collections.Generic;

namespace Kyoh.Lib.Win32API.NetResources
{
    /// <summary>ネットワークリソースの各ノードを表す <see cref="ResourceNode"/> オブジェクトのコレクション。</summary>
	[Serializable]
	public class ResourceNodeCollection : ICollection<ResourceNode>
	{
		private List<ResourceNode> mList;

        /// <summary><see cref="ResourceNodeCollection"/> クラスの新しいインスタンスを初期化します。</summary>
		public ResourceNodeCollection()
		{
			mList = new List<ResourceNode>();
		}

        /// <summary><see cref="ResourceNodeCollection"/> クラスの新しいインスタンスを初期化します。</summary>
        public ResourceNodeCollection(IEnumerable<ResourceNode> collection)
		{
			mList = new List<ResourceNode>(collection);
		}

		#region ICollection<NetResourceTreeNode> メンバ

        /// <summary>要素を追加します。</summary>
        /// <param name="item">追加する <see cref="ResourceNode"/></param>
		public void Add(ResourceNode item)
		{
			mList.Add(item);
		}

        /// <summary>要素を追加しますが、同じ名称の要素があった場合、新しい要素で置き換えます。</summary>
        /// <param name="item">追加する <see cref="ResourceNode"/></param>
		public void AddOrReplace(ResourceNode item)
		{
			var index = mList.FindIndex(node => node.LocalName == item.LocalName && node.RemoteName == item.RemoteName);
			if (index < 0)
				mList.Add(item);
			else
				mList.Insert(index, item);
		}

        /// <summary>複数の要素を追加します。</summary>
        /// <param name="nodes"> <see cref="ResourceNode"/> を列挙する <see cref="IEnumerable{T}"/> オブジェクト。</param>
		public void AddRange(IEnumerable<ResourceNode> nodes)
		{
			mList.AddRange(nodes);
		}

        /// <summary>要素をすべて削除します。</summary>
		public void Clear()
		{
			mList.Clear();
		}

        /// <summary>指定された <see cref="ResourceNode"/> オブジェクトが存在するかどうかを取得します。</summary>
        /// <param name="item">存在するかどうか確認する <see cref="ResourceNode"/> オブジェクト。</param>
        /// <returns>存在する場合は <c>true</c> 、それ以外の場合は <c>false</c> 。</returns>
		public bool Contains(ResourceNode item)
		{
			return mList.Contains(item);
		}

        /// <summary>要素を配列にコピーします。</summary>
        /// <param name="array">コピー対象の <see cref="ResourceNode"/> 配列。</param>
        /// <param name="arrayIndex">コピー先のオフセット。</param>
		public void CopyTo(ResourceNode[] array, int arrayIndex)
		{
			mList.CopyTo(array, arrayIndex);
		}

        /// <summary>要素の個数を取得します。</summary>
		public int Count
		{
			get { return mList.Count; }
		}

        /// <summary>このオブジェクトが読み取り専用かどうかを取得します。</summary>
		public bool IsReadOnly
		{
			get { return false; }
		}

        /// <summary>要素を削除します。</summary>
        /// <param name="item">削除する <see cref="ResourceNode"/> オブジェクト。</param>
        /// <returns>削除した場合は <c>true</c> 、指定された要素が存在しなかった場合は <c>false</c> 。</returns>
		public bool Remove(ResourceNode item)
		{
			return mList.Remove(item);
		}

        /// <summary>インデックスを指定して要素を取得・設定します。</summary>
        /// <param name="index">インデックス。</param>
        /// <returns>指定されたインデックスの要素。</returns>
		public ResourceNode this[int index]
		{
			get { return mList[index]; }
			set { mList[index] = value; }
		}

		#endregion

		#region IEnumerable<NetResourceTreeNode> メンバ

        /// <summary>要素を列挙します。</summary>
        /// <returns>要素を列挙する <see cref="IEnumerable{T}"/> オブジェクト。</returns>
		public IEnumerator<ResourceNode> GetEnumerator()
		{
			foreach (var item in mList)
				yield return item;
		}

		System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
		{
			foreach (var item in mList)
				yield return item;
		}

		#endregion

	}
}
